package net.cyue.nest.nestjava.common.data.http;

import com.fasterxml.jackson.core.JsonProcessingException;
import net.cyue.nest.nestjava.common.util.JSONUtil;
import net.cyue.nest.nestjava.common.util.ReflectUtil;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class HTTPRequestBody extends HashMap<String, Object> {

  public HTTPRequestBody() {
    super();
  }
  public HTTPRequestBody(Map map) {
    super(map);
  }

  public <T> T toObject(
    Class<T> clz
  ) throws IllegalArgumentException {
    T instance = null;
    try {
      instance = ReflectUtil.createInstance(clz);
    } catch (
      InvocationTargetException |
      InstantiationException |
      NoSuchMethodException e
    ) {
      e.printStackTrace();
      return null;
    }
    Field[] fields = clz.getDeclaredFields();
    for (final var f : fields) {
      final var value = this.get(f.getName());
      if (value == null) {
        continue;
      }
      try {
        Class<?> fieldType = f.getType();
        if (!fieldType.equals(value.getClass())) {
          if (fieldType.equals(String.class)) {
            ReflectUtil.setFieldValue(instance, f, String.valueOf(value));
          } else if (fieldType.equals(Date.class)) {
            ReflectUtil.setFieldValue(instance, f, new Date((String) value));
          } else if (fieldType.equals(Integer.class)) {
            ReflectUtil.setFieldValue(instance, f, Integer.parseInt((String) value));
          } else if (fieldType.equals(Long.class)) {
            ReflectUtil.setFieldValue(instance, f, Long.parseLong((String) value));
          } else if (fieldType.equals(Boolean.class)) {
            ReflectUtil.setFieldValue(instance, f, Boolean.parseBoolean((String) value));
          } else {
            throw new IllegalArgumentException("无法为 " + fieldType.getName() + " 设置 " + value.getClass().getName() + " 的值");
          }
          continue;
        }

        ReflectUtil.setFieldValue(instance, f, value);
      } catch (IllegalArgumentException | InvocationTargetException e) {
        e.printStackTrace();
      }
    }
    return instance;
  }


  public static HTTPRequestBody fromJSONString(String json)
    throws JsonProcessingException
  {
    if (json == null) {
      return new HTTPRequestBody();
    }
    final var map = JSONUtil.parseObject(json, Map.class);
    return new HTTPRequestBody(map);
  }

  public static HTTPRequestBody fromQueryString(String queryString) {
    if (queryString == null) {
      return new HTTPRequestBody();
    }
    final var body = new HTTPRequestBody();
    final var params = queryString.split("&");
    for (final var p : params) {
      final var kv = p.split("=");
      if (kv.length != 2) {
        continue;
      }
      final var k = kv[0];
      final var v = kv[1];
      body.put(k, v);
    }
    return body;
  }
}

